package com.cardmanager.pro.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cardmanager.pro.authorization.CreditCardManagerAuthorizationHandle;
import com.cardmanager.pro.business.ConsumeTaskPOJOBusiness;
import com.cardmanager.pro.business.CreditCardAccountBusiness;
import com.cardmanager.pro.business.RepaymentTaskPOJOBusiness;
import com.cardmanager.pro.pojo.ConsumeTaskPOJO;
import com.cardmanager.pro.pojo.CreditCardAccount;
import com.cardmanager.pro.pojo.RepaymentTaskPOJO;
import com.cardmanager.pro.util.RestTemplateUtil;

import cn.jh.common.utils.CommonConstants;
import cn.jh.common.utils.DateUtil;

@Controller
@EnableAutoConfiguration
public class TaskBillService {
	private final Logger LOG = LoggerFactory.getLogger(getClass());

	@Autowired
	private RestTemplateUtil util;

	@Autowired
	private RepaymentTaskPOJOBusiness repaymentTaskPOJOBusiness;

	@Autowired
	private ConsumeTaskPOJOBusiness consumeTaskPOJOBusiness;

	@Autowired
	private CreditCardAccountBusiness creditCardAccountBusiness;
	
	@Autowired
	private CreditCardManagerAuthorizationHandle creditCardManagerAuthorizationHandle;

	@RequestMapping(method = RequestMethod.POST, value = "/v1.0/creditcardmanager/query/taskbill/all/batchno")
	public @ResponseBody Object getAllRepaymentTaskByCreateTime(HttpServletRequest request,
			@RequestParam(value = "userId") String userId,
			@RequestParam(value = "creditCardNumber", required=false) String creditCardNumber,
			// status:0 全部批次 1:执行成功 2:等待执行 3:执行中 4:失败
			@RequestParam(value = "status", required = false, defaultValue = "0") String status,
			@RequestParam(value = "version", required = false, defaultValue = "1") String version,
			@RequestParam(value = "page", defaultValue = "0", required = false) int page,
			@RequestParam(value = "size", defaultValue = "20", required = false) int size,
			@RequestParam(value = "order", defaultValue = "DESC", required = false) Sort.Direction direction,
			@RequestParam(value = "sort", defaultValue = "createTime", required = false) String sortProperty) {
		Pageable pageable = new PageRequest(page, size, new Sort(direction, sortProperty));
		Map<String, Object> map = new HashMap<>();
		Map<String, Object> verifyStringFiledIsNullMap = creditCardManagerAuthorizationHandle
				.verifyStringFiledIsNull(userId);
		if (!CommonConstants.SUCCESS.equals(verifyStringFiledIsNullMap.get(CommonConstants.RESP_CODE))) {
			return verifyStringFiledIsNullMap;
		}
		List<Map<String, Object>> models = new ArrayList<>();
		List<Object[]> repaymentTaskPOJOs = null;
		if(creditCardNumber != null){
			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByCreateTimeAndVersion(userId, creditCardNumber,version, pageable);
			models = processingData(repaymentTaskPOJOs,status,version);
		}else{
			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByCreateTimeAndVersion(userId,version, pageable);
			models = processingData(repaymentTaskPOJOs,status,version);
		}
		
//		if ("0".equals(status)) {
//			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByCreateTime(userId, creditCardNumber, pageable);
//		} else if ("1".equals(status)) {
//			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByCreateTimeAndTaskStatus1(userId, creditCardNumber,
//					pageable);
//		} else if ("2".equals(status)) {
//			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByCreateTimeAndExecuteDate1(userId, creditCardNumber,
//					pageable);
//		} else if ("3".equals(status)) {
//			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByCreateTimeAndExecuteDate0(userId, creditCardNumber,
//					pageable);
//		} else if ("4".equals(status)) {
//			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByCreateTimeAndTaskStatus2(userId, creditCardNumber,
//					pageable);
//		}
		
		map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
		map.put(CommonConstants.RESULT, models);
		map.put(CommonConstants.RESP_MESSAGE, "查询成功");
		return map;
	}

	private List<Map<String, Object>> processingData(List<Object[]> repaymentTaskPOJOs,String status,String version) {
		List<Map<String, Object>> models = new ArrayList<>();
		if (repaymentTaskPOJOs != null && repaymentTaskPOJOs.size() > 0) {
			Map<String, Object> model = null;
			BigDecimal repaymentServiceCharge;
			BigDecimal consumeServiceCharge;
			BigDecimal sumConsumeAmount;
			Date nowTime = new Date();
			for (Object[] objs : repaymentTaskPOJOs) {
				model = new HashMap<>();
				String createTime = (String) objs[5];
				createTime = createTime.substring(0, createTime.lastIndexOf("."));
				
				int count = repaymentTaskPOJOBusiness.findByUserIdAndCreditCardNumberAndCreateTimeAndOrderStatus1CountAndVersion((String)objs[0],(String)objs[1],createTime,version);
				
				
				model.put("userId", objs[0]);
				model.put("creditCardNumber", objs[1]);
				// model.put("sumAmount", objs[2]);
				consumeServiceCharge = (((BigDecimal) objs[3]).add((BigDecimal)objs[11])).divide(BigDecimal.ONE.subtract((BigDecimal) objs[6]),2,BigDecimal.ROUND_UP).subtract((BigDecimal) objs[3]).subtract((BigDecimal)objs[11]);
//				repaymentServiceCharge = ((BigDecimal) objs[4]).subtract(consumeServiceCharge).setScale(2,
//						BigDecimal.ROUND_DOWN);

				if (BigDecimal.valueOf(0.02).compareTo(consumeServiceCharge) >= 0) {
					consumeServiceCharge = BigDecimal.ZERO;
					repaymentServiceCharge = BigDecimal.ZERO;
				}

				repaymentServiceCharge = ((BigDecimal)objs[11]).multiply(BigDecimal.valueOf(count));
				
				model.put("repaymentServiceCharge", repaymentServiceCharge);
				model.put("consumeServiceCharge", consumeServiceCharge);
				model.put("returnServiceCharge", objs[9]);
				if(((BigDecimal)objs[3]).compareTo(BigDecimal.ZERO) == 0){
					sumConsumeAmount = BigDecimal.ZERO;
				}else{
					sumConsumeAmount = ((BigDecimal)objs[3]).add(consumeServiceCharge).add(repaymentServiceCharge);
				}
				model.put("sumAmount",sumConsumeAmount);
				model.put("sumRealAmount", objs[3]);
				model.put("sumTotalServiceCharge", repaymentServiceCharge.add(consumeServiceCharge));
				model.put("createTime", createTime);
				model.put("rate", objs[6]);
				model.put("planSumAmount", objs[2]);
				int maxStatus = (int) objs[7];
				int minStatus = (int) objs[10];
				String executeDate = (String) objs[8];
				String nowDate = DateUtil.getDateStringConvert(new String(), nowTime, "yyyy-MM-dd");
				// if(status == 0){
				// if(nowDate.equals(executeDate)){
				// model.put("taskStatus", "3");
				// }else{
				// model.put("taskStatus", "2");
				// }
				// }else if(status == 1){
				// model.put("taskStatus", "1");
				// }else if(status == 2){
				// model.put("taskStatus", "4");
				// }
				
//				今天日期等于执行日期
				if (nowDate.equals(executeDate)) {
					model.put("taskStatus", "3");
//				最大任务状态等于0,未执行
				} else if (maxStatus == 0) {
					model.put("taskStatus", "2");
//				最大任务状态等于2,执行失败
				} else if (maxStatus == 2 || maxStatus ==4 ) {
					if(minStatus == 0){
						model.put("taskStatus", "3");
					}else{
						model.put("taskStatus", "4");
					}
//				最大任务状态等于1
				} else if (maxStatus == 1) {
					if(minStatus == 0){
						model.put("taskStatus", "3");
					}else{
						model.put("taskStatus", "1");
					}
				} else {
					if(((BigDecimal)objs[2]).compareTo(((BigDecimal)objs[3])) != 0){
						model.put("taskStatus", "4");
					}else{
						model.put("taskStatus", "2");
					}
				}
				
				if("0".equals(status)){
					models.add(model);
				}else if(((String)model.get("taskStatus")).equals(status)){
					models.add(model);
				}
			}
		}
		return models;
	}

	private <T> T processingData(T source) {
		Date nowTime = new Date();
		if (source instanceof RepaymentTaskPOJO) {
			RepaymentTaskPOJO model = (RepaymentTaskPOJO) source;
			int status = model.getTaskStatus();
			String executeDate = model.getExecuteDate();
			String nowDate = DateUtil.getDateStringConvert(new String(), nowTime, "yyyy-MM-dd");
			if (status == 0) {
				if (nowDate.equals(executeDate)) {
					model.setTaskStatus(3);
				} else {
					model.setTaskStatus(2);
				}
			} else if (status == 1) {
				model.setTaskStatus(1);
			} else if (status == 2 || status == 4) {
				model.setTaskStatus(4);
			}
			return (T) model;
		} else if (source instanceof ConsumeTaskPOJO) {
			ConsumeTaskPOJO model = (ConsumeTaskPOJO) source;
			int status = model.getTaskStatus();
			String executeDate = model.getExecuteDate();
			String nowDate = DateUtil.getDateStringConvert(new String(), nowTime, "yyyy-MM-dd");
			if (status == 0) {
				if (nowDate.equals(executeDate)) {
					model.setTaskStatus(3);
				} else {
					model.setTaskStatus(2);
				}
			} else if (status == 1) {
				model.setTaskStatus(1);
			} else if (status == 2 || status == 4) {
				model.setTaskStatus(4);
			}
			return (T) model;
		}
		return source;
	}
	
	/**
	 * 根据创建时间查询指定批次的还款任务
	 * @param request
	 * @param userId
	 * @param creditCardNumber
	 * @param createTime
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = "/v1.0/creditcardmanager/query/taskbill/by/createtime")
	public @ResponseBody Object ggetRepaymentTaskByCreateTime(HttpServletRequest request,
			@RequestParam(value = "userId") String userId,
			@RequestParam(value = "creditCardNumber") String creditCardNumber,
			@RequestParam(value = "createTime") String createTime,
			@RequestParam(value = "version",required=false,defaultValue="1") String version
			) {
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, Object> verifyStringFiledIsNullMap = creditCardManagerAuthorizationHandle
				.verifyStringFiledIsNull(userId, creditCardNumber, createTime);
		if (!CommonConstants.SUCCESS.equals(verifyStringFiledIsNullMap.get(CommonConstants.RESP_CODE))) {
			return verifyStringFiledIsNullMap;
		}

		createTime = createTime + ".0";
		List<RepaymentTaskPOJO> repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByCreateTimeAndVersion(userId,creditCardNumber, createTime,version);

		if (repaymentTaskPOJOs != null && repaymentTaskPOJOs.size() > 0) {
			for (RepaymentTaskPOJO repaymentTaskPOJO : repaymentTaskPOJOs) {
				repaymentTaskPOJO = processingData(repaymentTaskPOJO);
			}
		}
		map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
		map.put(CommonConstants.RESP_MESSAGE, "查询成功");
		map.put(CommonConstants.RESULT, repaymentTaskPOJOs);
		return map;
	}

	@RequestMapping(method = RequestMethod.POST, value = "/v1.0/creditcardmanager/query/taskbill/by/condition")
	public @ResponseBody Object getTaskStatus0RepaymentTask(HttpServletRequest request,
			@RequestParam(value = "userId") String userId,
			@RequestParam(value = "creditCardNumber") String creditCardNumber,
			// status字段含义: 0:返回还款任务 1:未执行的还款任务 2:已执行但未完成的还款任务 3:已执行且已完成的还款任务
			// 4:完成的还款任务中有失败消费任务的还款任务 5:执行失败的还款任务
			@RequestParam(value = "status", required = false, defaultValue = "0") String status,
			@RequestParam(value = "version", required = false, defaultValue = "1") String version,
			@RequestParam(value = "page", defaultValue = "0", required = false) int page,
			@RequestParam(value = "size", defaultValue = "20", required = false) int size,
			@RequestParam(value = "order", defaultValue = "DESC", required = false) Sort.Direction direction,
			@RequestParam(value = "sort", defaultValue = "createTime", required = false) String sortProperty) {
		Pageable pageable = new PageRequest(page, size, new Sort(direction, sortProperty));
		Map<String, Object> map = new HashMap<>();
		userId = userId.trim();
		creditCardNumber = creditCardNumber.trim();
		status = status.trim();
		List<RepaymentTaskPOJO> repaymentTaskPOJOs = null;

		Map<String, Object> verifyStringFiledIsNullMap = creditCardManagerAuthorizationHandle
				.verifyStringFiledIsNull(userId, creditCardNumber, status);
		if (!CommonConstants.SUCCESS.equals(verifyStringFiledIsNullMap.get(CommonConstants.RESP_CODE))) {
			return verifyStringFiledIsNullMap;
		}

		if ("0".equals(status)) {
			// 全部的还款任务:
			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByUserIdAndCreditCardNumberAndVersion(userId, creditCardNumber,version,
					pageable);
		} else if ("1".equals(status)) {
			// 未执行的还款任务:taskStatus:0;
			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByTaskStatus0RepaymentTaskAndVersion(userId, creditCardNumber,version,
					pageable);
		} else if ("2".equals(status)) {
			// 已执行未完成的还款任务:taskStatus:1 orderStatus:0;
			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByTaskStatus1AndOrderStatus0RepaymentTaskAndVersion(userId,
					creditCardNumber, version,pageable);
		} else if ("3".equals(status)) {
			// 已执行已完成的还款任务:taskStatus:1 orderStatus:1;
			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByTaskStatus1AndOrderStatus1RepaymentTaskAndVersion(userId,
					creditCardNumber, version,pageable);
		} else if ("4".equals(status)) {
			// 完成的还款任务中有失败消费任务: taskStatus:2 orderStatus:1;
			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByTaskStatus2AndOrderStatus1RepaymentTaskAndVersion(userId,
					creditCardNumber, version, pageable);
		} else if ("5".equals(status)) {
			// 执行失败的还款任务: taskStatus:2 orderStatus:0
			repaymentTaskPOJOs = repaymentTaskPOJOBusiness.findByTaskStatus2AndOrderstatus0RepaymentTaskAndVersion(userId,
					creditCardNumber, version,pageable);
		}
		map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
		map.put(CommonConstants.RESP_MESSAGE, "查询成功");
		map.put(CommonConstants.RESULT, repaymentTaskPOJOs);
		return map;
	}

	/**
	 * 根据任务id查询对应的子任务
	 * @param request
	 * @param repaymentTaskId
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = "/v1.0/creditcardmanager/query/consumetask/by/repaymenttaskid")
	public @ResponseBody Object getTaskStatus0RepaymentTask(HttpServletRequest request,
			@RequestParam(value = "repaymentTaskId") String repaymentTaskId) {
		Map<String, Object> map = new HashMap<>();
		Map<String, Object> verifyStringFiledIsNullMap = creditCardManagerAuthorizationHandle
				.verifyStringFiledIsNull(repaymentTaskId);
		if (!CommonConstants.SUCCESS.equals(verifyStringFiledIsNullMap.get(CommonConstants.RESP_CODE))) {
			return verifyStringFiledIsNullMap;
		}
		List tasks = consumeTaskPOJOBusiness.findByRepaymentTaskId(repaymentTaskId);
		ConsumeTaskPOJO model = null;
		Date nowTime = new Date();
		if (tasks != null && tasks.size() > 0) {
			for (Object obj : tasks) {
				model = (ConsumeTaskPOJO) obj;
				model = processingData(model);
				model.setTaskType(0);
			}
		}

		RepaymentTaskPOJO repaymentTaskPOJO = repaymentTaskPOJOBusiness.findByRepaymentTaskId(repaymentTaskId);
		if (repaymentTaskPOJO != null) {
			repaymentTaskPOJO = processingData(repaymentTaskPOJO);
			repaymentTaskPOJO.setTaskType(1);
		}
		tasks.add(repaymentTaskPOJO);
		map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
		map.put(CommonConstants.RESP_MESSAGE, "查询成功");
		map.put(CommonConstants.RESULT, tasks);
		return map;
	}

	@RequestMapping(method=RequestMethod.POST,value="/v1.0/creditcardmanager/delete/repaymenttask/by/repaymenttaskid")
	public @ResponseBody Object deleteRepaymentTaskByTaskStatus7(HttpServletRequest request,
			@RequestParam(value="repaymentTaskId")String repaymentTaskId
			){
		Map<String,Object>map = new HashMap<>();
		Map<String, Object> verifyStringFiledIsNullMap = creditCardManagerAuthorizationHandle.verifyStringFiledIsNull(repaymentTaskId);
		if(!CommonConstants.SUCCESS.equals(verifyStringFiledIsNullMap.get(CommonConstants.RESP_CODE))){
			return verifyStringFiledIsNullMap;
		}
		
		RepaymentTaskPOJO repaymentTaskPOJO = repaymentTaskPOJOBusiness.findByRepaymentTaskId(repaymentTaskId);
		
		if(repaymentTaskPOJO==null || repaymentTaskPOJO.getTaskStatus().intValue() == 7){
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESP_MESSAGE, "任务已删除!");
			return map;
		}
		
		Date nowDate = new Date();
		nowDate = DateUtil.getDateStringConvert(new Date(), nowDate, "yyyy-MM-dd");
		Date executeDate = DateUtil.getDateStringConvert(new Date(), repaymentTaskPOJO.getExecuteDate(), "yyyy-MM-dd");
		if(nowDate.getTime() >= executeDate.getTime()){
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESP_MESSAGE, "删除失败,只能删除今天以后的任务,当天任务及已执行的任务无法删除,当天还款任务将在23点之前进行出款!");
			return map;
		}
		
		repaymentTaskPOJO.setTaskStatus(7);
		repaymentTaskPOJO.setDescription(repaymentTaskPOJO.getDescription()+"|用户已删除");
		
		List<ConsumeTaskPOJO> consumeTaskPOJOs = consumeTaskPOJOBusiness.findByRepaymentTaskId(repaymentTaskId);
		for(ConsumeTaskPOJO consumeTaskPOJO:consumeTaskPOJOs){
			consumeTaskPOJO.setTaskStatus(7);
			consumeTaskPOJO.setDescription(consumeTaskPOJO.getDescription()+"|用户已删除");
		}
		consumeTaskPOJOBusiness.deleteRepaymentTaskAndConsumeTask(repaymentTaskPOJO,consumeTaskPOJOs);
//		map.put("repaymentTaskPOJO", repaymentTaskPOJO);
//		map.put("consumeTaskPOJOs", consumeTaskPOJOs);
		map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
		map.put(CommonConstants.RESP_MESSAGE, "删除成功!");
		return map;
	}
	
	@RequestMapping(method=RequestMethod.POST,value="/v1.0/creditcardmanager/find/repaymenttask/by/userid")
	public @ResponseBody Object getRepaymentTaskPOJOByUserId(HttpServletRequest request,
			@RequestParam(value="userId")String userId,
			@RequestParam(value="version",required=false,defaultValue="1")String version,
			@RequestParam(value = "page", defaultValue = "0", required = false) int page,
			@RequestParam(value = "size", defaultValue = "20", required = false) int size,
			@RequestParam(value = "order", defaultValue = "DESC", required = false) Sort.Direction direction,
			@RequestParam(value = "sort", defaultValue = "createTime", required = false) String sortProperty) {
		if(page < 0){
			page = 0;
		}
		Pageable pageable = new PageRequest(page, size, new Sort(direction, sortProperty));
		Map<String,Object>map = new HashMap<>();
		Page<RepaymentTaskPOJO> models = null;
		models = repaymentTaskPOJOBusiness.findByUserIdAndVersion(userId,version,pageable);
		
		map.put(CommonConstants.RESULT, models);
		map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
		map.put(CommonConstants.RESP_MESSAGE, "查询成功!");
		return map;
		
	}

	@RequestMapping(method=RequestMethod.POST,value="/v1.0/creditcardmanager/find/allamount/by/userid")
	public @ResponseBody Object getUserAllConsumeAmountAndRepaymentAmount(HttpServletRequest request,
			@RequestParam(value="userId")String userId,
			@RequestParam(value="creditCardNumber")String creditCardNumber,
			@RequestParam(value="version",required=false,defaultValue="1")String version
			){
		Map<String,Object>map = new HashMap<>();
		Map<String, Object> verifyStringFiledIsNullMap = creditCardManagerAuthorizationHandle.verifyStringFiledIsNull(userId,creditCardNumber);
		if(!CommonConstants.SUCCESS.equals(verifyStringFiledIsNullMap.get(CommonConstants.RESP_CODE))){
			return verifyStringFiledIsNullMap;
		}
		
		BigDecimal consumeAmount = consumeTaskPOJOBusiness.findAllRealAmountByUserIdAndCreditCardNumberAndOrderStatus1AndVersion(userId,creditCardNumber,version);
		BigDecimal repaymentAmount = repaymentTaskPOJOBusiness.findAllRealAmountByUserIdAndCreditCardNumberAndOrderStatus1AndVersion(userId,creditCardNumber,version);
		if(consumeAmount == null){
			consumeAmount = BigDecimal.ZERO;
		}
		if(repaymentAmount == null){
			repaymentAmount = BigDecimal.ZERO;
		}
//		consumeTaskPOJOBusiness
//		repaymentTaskPOJOBusiness
		map.put("consumeAmount", consumeAmount);
		map.put("repaymentAmount", repaymentAmount);
		map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
		map.put(CommonConstants.RESP_MESSAGE, "查询成功");
		return map;
	}
}
